package org.zjx.app.strategy.impl;

import lombok.SneakyThrows;
import org.zjx.analysis.analyze.battle.BattleAnalysis;
import org.zjx.app.action.battle.BattleAction;
import org.zjx.app.commnad.impl.BattleCommand;
import org.zjx.app.task.ProfessionType;
import org.zjx.command.entity.Sects;
import org.zjx.command.state.AccountState;
import org.zjx.command.state.GameState;
import org.zjx.command.state.RoleState;
import org.zjx.window.action.IAction;
import org.zjx.window.action.impl.DelayAction;
import org.zjx.window.strategy.IStrategy;
import org.zjx.window.window.IWindow;
import org.zjx.window.window.impl.GameWindow;
import org.zjx.command.entity.Character;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class BattleStrategy implements IStrategy {
    private GameState gameState;


    @SneakyThrows
    @Override
    public IAction analyze(IWindow iWindow) {
        gameState = iWindow.getState().getGameState();
        RoleState roleState = iWindow.getState().getState(RoleState.class);
        AccountState accountState = iWindow.getState().getState(AccountState.class);
        Sects sect = accountState.getSect();
        int currentMana = roleState == null ? 1000 : roleState.getMana();

        // 1. 优先处理复活逻辑（修改为返回boolean）
        int reviveTarget = revivePosition();
        if (reviveTarget != -1) {
            if (handleRevive(sect, currentMana, reviveTarget)) {
                return new BattleAction(iWindow); // 成功处理复活则返回
            }
            // 无法复活则继续后续流程
        }

        // 2. 处理濒危队友（修改后的逻辑）
        int endangeredTarget = endangeredPosition();
        if (endangeredTarget != -1) {
            if (handleEndangered(sect, currentMana, endangeredTarget)) {
                return new BattleAction(iWindow); // 成功处理濒危则返回
            }
            // 无法处理则继续后续流程
        }

        // 3. 攻击逻辑保持不变
        int attackTarget = monsterPosition();
        if (attackTarget == -1) {
            return new DelayAction(iWindow,1000);
        }

        // 根据职业类型处理攻击逻辑
        if (ProfessionType.isPhysical(sect)) {
            handlePhysicalAttack(sect, currentMana, attackTarget);
        } else if (ProfessionType.isMajor(sect)) {
            handleMagicalAttack(sect, currentMana, attackTarget);
        } else if (ProfessionType.isRevive(sect)) {
            handleHealerSupport(currentMana);
        } else {
            // 混合系默认使用物理攻击
            gameState.setCommand(new BattleCommand("物理", "普通攻击", attackTarget, true));
        }
        return new BattleAction(iWindow);
    }

    @Override
    public String getName() {
        return "战斗策略";
    }

    @Override
    public int getPriority() {
        return 50;
    }

    @Override
    public boolean isApplicable(IWindow iWindow) {
        if (!(iWindow  instanceof  GameWindow)) return false;
        gameState = iWindow.getState().getGameState();
        BattleAnalysis battleAnalysis = new BattleAnalysis(iWindow.getScreenshot());
        boolean applicable = battleAnalysis.isBattle();
        if (applicable) {
            gameState.setOtherSideCharacters(battleAnalysis.getOtherSide());
            gameState.setOurSideCharacters(battleAnalysis.getOurSide());
        }
        return applicable;
    }


    // 处理物理系攻击
    private void handlePhysicalAttack(Sects sect, int currentMana, int target) {
        String skill = defaultSkills(sect, ProfessionType.PHYSICAL);
        int skillCost = getSkillManaCost(skill); // 获取技能蓝耗

        if (currentMana >= skillCost) {
            gameState.setCommand(new BattleCommand("法术", skill, target, true));
        } else {
            // 蓝量不足使用普通攻击
            gameState.setCommand(new BattleCommand("物理", "普通攻击", target, true));
        }
    }

    // 处理法术系攻击
    private void handleMagicalAttack(Sects sect, int currentMana, int target) {
        String skill = defaultSkills(sect, ProfessionType.MAGICAL);
        int skillCost = getSkillManaCost(skill);

        if (currentMana >= skillCost) {
            gameState.setCommand(new BattleCommand("法术", skill, target, true));
        } else {
            // 蓝量不足选择防御或使用回蓝道具
            String manaItem = hasManaItem();
            if (manaItem != null && !manaItem.isEmpty()) {
                gameState.setCommand(new BattleCommand("道具", manaItem, 0, false));
            } else {
                gameState.setCommand(new BattleCommand("防御", "防御", 0, false));
            }
        }
    }

    // 处理治疗系行为
    private void handleHealerSupport(int currentMana) {
        // 优先治疗濒危队友已在主逻辑处理
        // 这里处理无濒危队友时的默认行为
        if (currentMana < 200) {
            String manaItem = hasManaItem();
            if (manaItem != null && !manaItem.isEmpty()) {
                gameState.setCommand(new BattleCommand("道具", manaItem, 0, false));
            } else {
                gameState.setCommand(new BattleCommand("防御", "防御", 0, false));
            }
        } else {
            gameState.setCommand(new BattleCommand("防御", "防御", 0, false));
        }
    }

    // 处理复活逻辑
    private boolean handleRevive(Sects sects, int currentMana, int target) {
        if (ProfessionType.isRevive(sects) && currentMana >= getSkillManaCost("复活技能")) {
            String defaultSkills = defaultSkills(sects, ProfessionType.REVIVE);
            gameState.setCommand(new BattleCommand("法术", defaultSkills, target, false));
            return true;
        }

        String reviveItem = hasReviveItem();
        if (reviveItem != null && !reviveItem.isEmpty()) {
            gameState.setCommand(new BattleCommand("道具", reviveItem, target, false));
            return true;
        }

        return false;
    }

    // 处理治疗逻辑
    private boolean handleEndangered(Sects sects, int currentMana, int target) {
        // 治疗职业优先使用技能
        if (ProfessionType.isHealer(sects) || ProfessionType.isHybrid(sects)) {
            String defaultSkills = defaultSkills(sects, ProfessionType.HEALER);
            if (currentMana >= getSkillManaCost(defaultSkills)) {
                gameState.setCommand(new BattleCommand("法术", defaultSkills, target, false));
                return true;
            }
        }

        // 所有职业检查恢复道具
        String healItem = hasHealItem();
        if (healItem != null && !healItem.isEmpty()) {
            gameState.setCommand(new BattleCommand("道具", healItem, target, false));
            return true;
        }

        // 无法处理返回false
        return false;
    }


    // 以下为辅助方法（需根据实际游戏实现）
    private int getSkillManaCost(String skill) {
        // 实现技能蓝耗查询逻辑
        switch (skill) {
//            case "横扫千军":
//                return 0;
//            case "龙卷雨击":
//                return 100;
            case "杨柳甘露":
                return 200;
            case "推气过宫":
                return 120;
            default:
                return 10000;  //进行普通攻击
        }
    }

    private String hasManaItem() {
        // 实现检查是否有回蓝道具
//        return gameState.getItemCount("回蓝道具") > 0;
        return null;
    }

    private String hasReviveItem() {
        // 实现检查是否有复活道具
//        return gameState.getItemCount("九转回魂丹") > 0;
        return null;
    }

    // 新增检查治疗道具方法
    private String hasHealItem() {
        // 实现检查是否有治疗道具（如金创药）
//        return gameState.getItemCount("金创药") > 0;
        return null;
    }


    //可攻击的怪物 序号优先级
    public int monsterPosition() {
        List<Character> characters = gameState.getOtherSideCharacters();
        if (characters == null || characters.isEmpty()) return 0;
        return IntStream.range(0, characters.size())
                .filter(i -> characters.get(i) != null)
                .findFirst()
                .orElse(-1); // 如果全部为null则返回-1
    }

    //待复活的队友
    public int revivePosition() {
        List<Character> characters = gameState.getOurSideCharacters();
        if (characters == null || characters.isEmpty()) return -1;
        return IntStream.range(0, characters.size())
                .filter(i -> characters.get(i) != null && characters.get(i).getHpPercentage() <= 0)
                .findFirst()
                .orElse(-1); // 如果全部为null则返回-1
    }

    /**
     * 获取濒危队友位置
     * 条件1: 当有3个及以上队友血量<60
     * 条件2: 或任意1个队友血量<40
     * 满足任一条件时返回血量最低的队友序号
     *
     * @return 濒危队友序号，若无满足条件则返回-1
     */
    public int endangeredPosition() {
        List<Character> characters = gameState.getOurSideCharacters();
        if (characters == null || characters.isEmpty()) return -1;
        // 统计危险血量队友
        List<Integer> endangered = IntStream.range(0, characters.size())
                .filter(i -> characters.get(i) != null && characters.get(i).getHpPercentage() < 60)
                .boxed()
                .collect(Collectors.toList());

        // 检查是否有血量<40的队友
        boolean hasCritical = characters.stream()
                .filter(Objects::nonNull)
                .anyMatch(b -> b.getHpPercentage() < 40);

        // 满足条件时返回血量最低的队友
        if (endangered.size() >= 3 || hasCritical) {
            return IntStream.range(0, characters.size())
                    .filter(i -> characters.get(i) != null)
                    .boxed()
                    .min(Comparator.comparingInt(i -> characters.get(i).getHpPercentage()))
                    .orElse(-1);
        }


        return -1;
    }

    private String defaultSkills(Sects sects, ProfessionType professionType) {
        switch (sects) {
            case DA_TANG_GUAN_FU:
                return "横扫千军";
            case LONG_GONG:
                return "龙卷雨击";
            default:
                return "牛刀小试";
        }
    }
}
